package com.wang.gallerybackend.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wang.gallerybackend.annotation.AuthCheck;
import com.wang.gallerybackend.common.AjaxResult;
import com.wang.gallerybackend.common.BaseResponse;
import com.wang.gallerybackend.common.DeleteRequest;
import com.wang.gallerybackend.constant.UserConstant;
import com.wang.gallerybackend.exception.BusinessException;
import com.wang.gallerybackend.exception.ErrorCode;
import com.wang.gallerybackend.exception.ThrowUtils;
import com.wang.gallerybackend.manager.auth.SpaceUserAuthManager;
import com.wang.gallerybackend.model.dto.space.*;
import com.wang.gallerybackend.model.entity.Space;
import com.wang.gallerybackend.model.entity.User;
import com.wang.gallerybackend.model.enums.SpaceLevelEnum;
import com.wang.gallerybackend.model.vo.SpaceVO;
import com.wang.gallerybackend.service.SpaceService;
import com.wang.gallerybackend.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 汪
 */
@Slf4j
@RestController
@RequestMapping("/space")
public class SpaceController {


	@Resource
	private UserService userService;
	@Resource
	private SpaceService spaceService;
	@Resource
	private SpaceUserAuthManager spaceUserAuthManager;


	/**
	 * 更新空间（仅管理员可用）
	 *
	 * @param spaceUpdateRequest 空间更新参数
	 * @return 响应
	 */
	@PostMapping("/update")
	@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
	public BaseResponse<Boolean> updateSpace(@RequestBody SpaceUpdateRequest spaceUpdateRequest,
											 HttpServletRequest request) {
		//获取用户
		User loginUser = userService.getLoginUser(request);
		if (spaceUpdateRequest == null || spaceUpdateRequest.getId() <= 0) {
			throw new BusinessException(ErrorCode.PARAMS_ERROR);
		}

		// 将实体类和 DTO 进行转换
		Space space = new Space();
		BeanUtils.copyProperties(spaceUpdateRequest, space);
		spaceService.fillSpaceBySpaceLevel(space);
		// 数据校验
		spaceService.validSpace(space, false);
		// 判断是否存在
		long id = spaceUpdateRequest.getId();
		Space oldSpace = spaceService.getById(id);
		ThrowUtils.throwIf(oldSpace == null, ErrorCode.NOT_FOUND_ERROR);

		// 操作数据库
		boolean result = spaceService.updateById(space);
		ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);

		return AjaxResult.success(true);
	}


	/**
	 * 删除空间
	 * @param deleteRequest 删除参数
	 * @return 响应
	 */
	@PostMapping("/delete")
	public BaseResponse<Boolean> deleteSpace(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
		if (deleteRequest == null || deleteRequest.getId() <= 0) {
			throw new BusinessException(ErrorCode.PARAMS_ERROR);
		}
		Long id = deleteRequest.getId();
		User loginUser = userService.getLoginUser(request);
		Space oldSpace = spaceService.getById(id);
		if (oldSpace == null) {
			throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
		}
		// 仅本人或管理员可删除
		spaceService.checkSpaceAuth(loginUser, oldSpace);
		boolean result = spaceService.removeById(id);
		if (!result) {
			throw new BusinessException(ErrorCode.OPERATION_ERROR);
		}
		return AjaxResult.success(true);
	}

	/**
	 * 根据 id 获取空间（仅管理员可用）
	 */
	@GetMapping("/get")
	@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
	public BaseResponse<Space> getSpaceById(long id) {
		ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
		// 查询数据库
		Space space = spaceService.getById(id);
		ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR);
		// 获取封装类
		return AjaxResult.success(space);
	}

	/**
	 * 根据 id 获取空间（封装类）
	 */
	@GetMapping("/get/vo")
	public BaseResponse<SpaceVO> getSpaceVOById(Long id, HttpServletRequest request) {
		User loginUser = userService.getLoginUser(request);
		ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
		//查询数据库
		Space space = spaceService.getById(id);
		ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR);
		List<String> permissionList = spaceUserAuthManager.getPermissionList(space, loginUser);
		SpaceVO spaceVO = spaceService.getSpaceVO(space, request);
		spaceVO.setPermissionList(permissionList);
		// 获取封装类
		return AjaxResult.success(spaceVO);
	}

	/**
	 * 分页获取空间列表（仅管理员可用）
	 */
	@PostMapping("/list/page")
	@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
	public BaseResponse<Page<Space>> listSpaceByPage(@RequestBody SpaceQueryRequest spaceQueryRequest) {
		long current = spaceQueryRequest.getPageNum();
		long size = spaceQueryRequest.getPageSize();
		// 查询数据库
		Page<Space> spacePage = spaceService.page(new Page<>(current, size),
				spaceService.getQueryWrapper(spaceQueryRequest));
		return AjaxResult.success(spacePage);
	}

	/**
	 * 分页获取空间列表（封装类）
	 */
	@PostMapping("/list/page/vo")
	public BaseResponse<Page<SpaceVO>> listSpaceVOByPage(@RequestBody SpaceQueryRequest spaceQueryRequest,
														 HttpServletRequest request) {
		long current = spaceQueryRequest.getPageNum();
		long size = spaceQueryRequest.getPageSize();
		// 限制爬虫
		ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
		// 查询数据库
		Page<Space> spacePage = spaceService.page(new Page<>(current, size),
				spaceService.getQueryWrapper(spaceQueryRequest));
		// 获取封装类
		return AjaxResult.success(spaceService.getSpaceVOPage(spacePage, request));
	}


	/**
	 * 编辑空间（给用户使用）
	 */
	@PostMapping("/edit")
	public BaseResponse<Boolean> editSpace(@RequestBody SpaceEditRequest spaceEditRequest, HttpServletRequest request) {
		if (spaceEditRequest == null || spaceEditRequest.getId() <= 0) {
			throw new BusinessException(ErrorCode.PARAMS_ERROR);
		}
		// 在此处将实体类和 DTO 进行转换
		Space space = new Space();
		BeanUtils.copyProperties(spaceEditRequest, space);
		// 自动填充数据
		spaceService.fillSpaceBySpaceLevel(space);
		// 设置编辑时间
		space.setEditTime(new Date());
		// 数据校验
		spaceService.validSpace(space, false);
		User loginUser = userService.getLoginUser(request);
		// 判断是否存在
		long id = spaceEditRequest.getId();
		Space oldSpace = spaceService.getById(id);
		ThrowUtils.throwIf(oldSpace == null, ErrorCode.NOT_FOUND_ERROR);
		spaceService.checkSpaceAuth(loginUser, oldSpace);
		// 操作数据库
		boolean result = spaceService.updateById(space);
		ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
		return AjaxResult.success(true);
	}

	/**
	 * 添加空间（给用户使用）
	 */
	@PostMapping("/add")
	public BaseResponse<Long> addSpace(@RequestBody SpaceAddRequest spaceAddRequest, HttpServletRequest request) {
		ThrowUtils.throwIf(spaceAddRequest == null, ErrorCode.PARAMS_ERROR);
		User loginUser = userService.getLoginUser(request);
		return AjaxResult.success(spaceService.addSpace(spaceAddRequest, loginUser));
	}

	/**
	 * 获取空间等级列表，便于前端展示
	 * @return
	 */
	@GetMapping("/list/level")
	public BaseResponse<List<SpaceLevel>> listSpaceLevel() {
		List<SpaceLevel> spaceLevelList = Arrays.stream(SpaceLevelEnum.values())
				.map(spaceLevelEnum ->
						new SpaceLevel(spaceLevelEnum.getValue(), spaceLevelEnum.getText(),
								spaceLevelEnum.getMaxCount(), spaceLevelEnum.getMaxSize())
				).collect(Collectors.toList());
		return AjaxResult.success(spaceLevelList);
	}
}